#ifndef SKETCHMODEL_H_
#define SKETCHMODEL_H_

#include <string>
#include <list>
#include <map>
#include "basic/Coordinate.h"
#include "ads/typesDefinition.h"
#include "basic/ConstraintData.h"

namespace common {

class PointDb;
class PrimitiveDb;
class ConstraintDb;
class ParameterDb;
class ModelSolver;


/**
 * SketchModel is based on QObject
 * have a facility to send and receive
 * signal from View
 */
class SketchModel {


	PointDb* pointDb;
	PrimitiveDb* primitiveDb;
	ConstraintDb* constraintDb;
	ParameterDb* parameterDb;
	ModelSolver* modelSolver;

	std::list<std::string> messages;

	/**
	 * Add Message
	 */
	void addMsg(const std::string& msg);

	void setUpDataBases();

public:
	SketchModel();

	void setSolver(ModelSolver* solver);

	// slots
	void solve();
	void relax();
	// segments slots

	void addLine(Coordinate c1,Coordinate c2);
	void addCircle(Coordinate c1,Coordinate c2);
	void addSegment(std::list<Coordinate> cSet);

	void pointAdjust(int i, Coordinate c1);

	// constraint slots
	void addConnectPoints(int k,int l);
	void addFixPoint(int k);
	void addPerpendicular(int k,int l, int m,int n);
	void addHorizontal(int k,int l);
	void addVertical(int k,int l);
	void addParallel(int k,int l, int m,int n);
	void addSameLength(int k,int l, int m,int n);
	void addDistance(int k,int l,skreal paramValue);
	void addAngle(int k,int l,int m,int n,skreal paramValue);
	void addTangency(int k,int l,int m,int n);
	// TABLE SLOT
	void removeConstraint(int id);
	void removePrimitive(int id);
	void setParameter(int id,skreal value);

	// TABLE DATA
	std::map<int,std::string> getPrimitiveData();
	std::list<ConstraintData> getConstraintData();
	std::map<int,skreal> getParameterData();

	// GRAPHICS VIEW + above getPrimitiveData()
	std::map<int,Coordinate> getPrimitivePoints(int i);

	std::string report();

	virtual ~SketchModel();
};

}

#endif /* SKETCHMODEL_H_ */
